package org.sundatagroup.aurora.core.service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.sundatagroup.aurora.core.dao.ParticleDao;
import org.sundatagroup.aurora.core.entity.model.ParticleModel;
import org.sundatagroup.aurora.core.entity.particle.IndexParticle;
import org.sundatagroup.aurora.core.entity.particle.ModuleParticle;
import org.sundatagroup.aurora.core.entity.particle.Particle;
import org.sundatagroup.aurora.core.entity.particle.ParticleFactory;
import org.sundatagroup.aurora.core.entity.particle.ParticleGroup;
import org.sundatagroup.aurora.core.entity.particle.ProjectParticle;
import org.sundatagroup.aurora.core.entity.pojo.Module;
import org.sundatagroup.aurora.core.entity.pojo.Project;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

/**
 * <p>封装 {@link Particle} 相关操作的服务层, 用于查询
 * </p>
 * 
 * @author Zdream
 * @date 2018-06-08
 * @since 0.2.0
 */
@Service
public class ParticleService {

    private final static Logger LOGGER = LoggerFactory.getLogger(ParticleService.class);
	
	@Autowired
	ParticleDao dao;
	
	public void assemble(Project p) {
		// 工程域 particle
		int pid = p.getPid();
		ParticleGroup pg = ParticleFactory.buildGroup(pid, dao.findAllByProject(pid));
		ProjectParticle pjp = pg.getProjectParticle();
		
		// 一类 module 的, mid - particle
		List<Module> modules = p.getModules();
		
		JsonObject options = p.getOptions();
		if (options == null) {
			options = new JsonObject();
			p.setOptions(options);
		}
		
		int index = 0;
		for (Iterator<Module> it = modules.iterator(); it.hasNext(); index++) {
			Module module = it.next();
			
			// module
			int mid = module.getMid();
			ModuleParticle mp = pg.getModuleParticle(mid);
			
			// index
			IndexParticle ip = pg.getIndexParticle(index);
			
			// 装入
			List<Particle> list = new ArrayList<>(3);
			if (pjp != null) {
				list.add(pjp);
			}
			if (mp != null) {
				list.add(mp);
			}
			if (ip != null) {
				list.add(ip);
			}
			p.getParticles().add(list);
			
			JsonObject o = mergeParticle(list);
			if (o != null) {
				options.add(Integer.toString(index), o);
				LOGGER.debug(String.format("工程 #%d, index:%d particle: %s", pid, index, o));
			}
		}
	}
	
	/**
	 * 合并原子配置
	 * @param list
	 * @return
	 */
	private JsonObject mergeParticle(List<Particle> list) {
		if (list == null || list.isEmpty()) {
			return null;
		}
		
		JsonObject jo = new JsonObject();
		list.forEach((p) -> {
			JsonObject data = p.getData();
			if (data == null) {
				return;
			}
			
			for (Iterator<Entry<String, JsonElement>> it = data.entrySet().iterator(); it.hasNext();) {
				Entry<String, JsonElement> entry = it.next();
				jo.add(entry.getKey(), entry.getValue());
			}
		});
		
		return jo;
	}
	
	/**
	 * 获取整个 Project 域适用的 particle
	 * @param pid
	 *   project.pid
	 * @return
	 */
	public ProjectParticle findByProjectScope(int pid) {
		ParticleModel pm = dao.findByProjectScope(pid);
		if (pm == null) {
			return null;
		}
		return ProjectParticle.of(pm);
	}
	
	/**
	 * 获取整个 Project 域同一个指定的 module 的 particle
	 * @param pid
	 *   project.pid
	 * @param mid
	 *   module.mid
	 * @return
	 */
	public ModuleParticle findByModuleAndProject(int pid, int mid) {
		ParticleModel pm = dao.findByModuleInProject(pid, mid);
		if (pm == null) {
			return null;
		}
		return ModuleParticle.of(pm);
	}
	
	/**
	 * 获取整个 Project 域指定索引的 particle, 这个是唯一的
	 * @param pid
	 *   project.pid
	 * @param index
	 *   索引, project 的第几个 module
	 * @return
	 */
	public IndexParticle findByIndexAndProject(int pid, int index) {
		ParticleModel pm = dao.findByIndexInProject(pid, index);
		if (pm == null) {
			return null;
		}
		return IndexParticle.of(pm);
	}

}
